package com.dev.ac.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;

import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.Texts;
import com.dev.ac.common.Const;
import com.dev.ac.common.Result;
import com.dev.ac.entity.AActive;
import com.dev.ac.entity.AAdmin;
import com.dev.ac.entity.AApplication;
import com.dev.ac.entity.AUser;
import com.dev.ac.entity.*;
import com.dev.ac.exception.WebException;
import com.dev.ac.mapper.AAuthenticationMapper;
import com.dev.ac.service.*;
import com.dev.ac.mapper.AActiveMapper;
import com.dev.ac.util.HtmlConvertWordUtil;
import com.dev.ac.util.JwtUtil;
import com.dev.ac.util.RedisUtil;
import com.dev.ac.util.XWPFDocumentUtils;
import com.dev.ac.vo.ActiveVo;
import com.dev.ac.vo.MyActiveVo;
import com.dev.ac.vo.MyParticipationActivie;

import com.dev.ac.vo.SearchVo;

import com.dev.ac.vo.SearchVo;

import com.dev.ac.vo.UserNewPassword;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.jsonwebtoken.Claims;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;

import java.math.BigDecimal;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author object
 * @description 针对表【a_active】的数据库操作Service实现
 * @createDate 2024-04-14 16:13:23
 */
@Service
public class AActiveServiceImpl extends ServiceImpl<AActiveMapper, AActive>
		implements AActiveService {

	@Autowired
	RedisUtil redisUtil;
	@Autowired
	AAdminService aAdminService;
	@Autowired
	ResourceLoader resourceLoader;
	@Autowired
	AApplicationService aApplicationService;
	@Autowired
	AUserService aUserService;
	@Autowired
	AActiveMapper aActiveMapper;
	@Autowired
	JwtUtil jwtUtil;
	@Autowired
	AAuthenticationMapper aAuthenticationMapper;

	private static final String filePath = System.getProperty("user.dir") + "/file/";

	@Override
	public Page<AActive> selctAll(Integer currentPage) {
		Page<AActive> page = this.page(new Page<>(currentPage, 8), new QueryWrapper<AActive>()
				.ne("status", 4));
		for (AActive aActive : page.getRecords()) {
			AAdmin aAdmin = aAdminService.getById(aActive.getAdminId());
			if (aAdmin != null) {
				aActive.setAAdmin(aAdmin);
			}
		}
		return page;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Object insertActive(ActiveVo activeVo) throws IOException {
		Map<String, Object> datas = new HashMap<>();


		// 将数据存储到数据库
		AActive aActive = new AActive();
		String uuid = String.valueOf(UUID.randomUUID()).replace("-", "");
		aActive.setActiveId(uuid);
		aActive.setActiveName(activeVo.getTitle());
		aActive.setActiveDescription(activeVo.getDescription());
		aActive.setActiveContent(activeVo.getContent());
		aActive.setType(activeVo.getActiveType());
		BigDecimal score = activeVo.getScore();
		aActive.setScore(score.doubleValue());
		aActive.setCreateTime(activeVo.getCreateTime().toLocalDateTime());
		aActive.setDeadTime(activeVo.getDeadTime().toLocalDateTime());
		aActive.setPeopleCount(activeVo.getPeopleCount());
		aActive.setStatus(activeVo.getStatus());
		aActive.setIsDelete(0);
		aActive.setAcriveAddress(activeVo.getAddress());
		aActive.setAdminId(aAdminService.getCurrentId());
		aActive.setSecondScore(activeVo.getSecondScore());
		aActive.setLaborScore(activeVo.getLaborScore());
		aActive.setEducationScore(activeVo.getEducationScore());
		if (activeVo.getDepartment() != null) {
			aActive.setDepartment(activeVo.getDepartment());
		}
		aActive.setFilePath(activeVo.getTitle() + "-" + aActive.getActiveId());

		boolean save = this.save(aActive);
		if (!save) {
			return false;
		}

		Resource resource = resourceLoader.getResource("classpath:static/template.docx");
		//获1.txt的取相对路径
		String path = resource.getFile().getPath();
		System.out.println(path);

		XWPFDocument document = HtmlConvertWordUtil.htmlConvertWord(activeVo.getContent());

		// 需要将内容通过模板将数据放进去
		datas.put("title", Texts.of(activeVo.getTitle()).fontSize(20).color("000000").bold().create());
		datas.put("createTime", Texts.of(LocalDateTimeUtil.format(activeVo.getCreateTime().toLocalDateTime(), "yyyy-MM-dd")).fontSize(10).create());
		datas.put("deadTime", Texts.of(LocalDateTimeUtil.format(activeVo.getDeadTime().toLocalDateTime(), "yyyy-MM-dd")).fontSize(10).create());
		datas.put("content", Texts.of(activeVo.getContent()).fontSize(10).create());
		// 添加模板
		XWPFTemplate compile = XWPFTemplate.compile(path);
		// 添加数据
		compile.render(datas);
		// 将数据转为文件输出到指定目录

		XWPFDocument xwpfDocument = compile.getXWPFDocument();

		XWPFDocumentUtils.copyXWPFDocumentContent(document, xwpfDocument);


		compile.writeToFile(filePath + activeVo.getTitle() + "-" + aActive.getActiveId() + ".docx");

		compile.close();
		document.close();
		return true;
	}

	/**
	 * 获取所有活动信息
	 **/
	@Override
	public Object GetAllAActiveInformationService(Integer pageNum) {
		Page<AActive> activePage = this.page(new Page<>(pageNum, 30), new LambdaQueryWrapper<AActive>()
				.apply("status!=0")
				.apply("status!=4")
						.apply("is_delete!=1")
				.apply(" DATE_SUB(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 30 DAY) < DATE_FORMAT(dead_time,'%Y-%m-%d')")
				.orderByDesc(AActive::getDeadTime));
		for (AActive active : activePage.getRecords()) {
			long count = aApplicationService.count(new QueryWrapper<AApplication>().eq("active_id", active.getId()));
			active.setApplicationCount(count);
		}
		return activePage;
	}

	/**
	 * 活动报名添加
	 **/
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Object EvenRegistrationService(Integer aApplication, HttpServletRequest httpServerRequest) {
		String token = httpServerRequest.getHeader("token");
		Claims claimByToken = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		Integer subject = Integer.valueOf(claimByToken.getSubject());
		AApplication aApplication1 = new AApplication();
		AActive aActive = this.getOne(new QueryWrapper<AActive>()
				.eq("id", aApplication));
		long count = aApplicationService.count(new QueryWrapper<AApplication>().eq("active_id", aActive.getId()));//参加活动的人数
		long count1 = aApplicationService.count(new QueryWrapper<AApplication>()
				.eq("active_id", aActive.getId())
				.eq("user_id", subject));//判断该用户是否已经报名了

		aApplication1.setActiveId(aApplication);
		aApplication1.setCreateTime(LocalDateTime.now());
		aApplication1.setUserId(subject);
		if ((count >= aActive.getPeopleCount() && aActive.getPeopleCount() != 0) || aActive.getDeadTime().isBefore(LocalDateTime.now())) {
			throw new WebException("当前人数已满或已截至");
		} else if (aActive.getCreateTime().isAfter(LocalDateTime.now())) {
			throw new WebException("还未到报名时间");
		} else if (count1 > 0) {
			throw new WebException("已报名，无需再次报名");
		} else if (aActive.getStatus() == 3) {
			throw new WebException("活动已结束，无法报名");
		} else if (aActive.getStatus() == 4 || aActive.getStatus() == 0) {
			throw new WebException("该活动暂时无法报名");
		}
		boolean save = aApplicationService.save(aApplication1);
		return save;
	}

	/**
	 * 查询我参加的活动
	 **/
	@Override
	public Object MyParticipationActivieService(MyActiveVo myActiveVo, HttpServletRequest httpServletRequest) {
		PageHelper.startPage(myActiveVo.getPageNum(), 30);
		String token = httpServletRequest.getHeader("token");
		Claims claimByToken = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		Integer subject = Integer.valueOf(claimByToken.getSubject());
		List<MyParticipationActivie> myParticipationActivies = aActiveMapper.MyParticipationActivieMapper(subject, myActiveVo);
		PageInfo<MyParticipationActivie> myParticipationActiviePageInfo = new PageInfo<>(myParticipationActivies);
		return myParticipationActiviePageInfo;
	}

	/**
	 * 管理员活动审核
	 *
	 * @param ids
	 * @param activeId 活动id
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean examine(List<Integer> ids, Integer type) {
		boolean a = false;
		// type：1-通过，2-不通过
		if (type == 1) {
			a = this.update(new UpdateWrapper<AActive>()
					.in("id", ids)
					.set("status", 1)
			);
		} else {
			a = this.update(new UpdateWrapper<AActive>()
					.in("id", ids)
					.set("status", 5)
			);
		}
		return a;
	}

	@Override
	public Object selectById(Integer id) {
		AActive aActive = this.getById(id);
		List<AApplication> aApplications = aApplicationService.list(new QueryWrapper<AApplication>()
				.eq("active_id", id)
				.orderByDesc("create_time")
		);
		for (AApplication aApplication : aApplications) {
			AUser aUser = aUserService.getById(aApplication.getUserId());
			aApplication.setAUser(aUser);
		}
		return MapUtil.builder()
				.put("activeInfo", aActive)
				.put("application", aApplications)
				.build();
	}

	/***获取我的总分数信息**/
	private Double count=0.0;
	private Double secondscore=0.0;
	private Double laborscore=0.0;
	private Double educationscore=0.0;
	@Override
	public Object SelectTotalScoreService(HttpServletRequest httpServletRequest) {
		count=0.0;
		secondscore=0.0;
		laborscore=0.0;
		educationscore=0.0;
		HashMap<String,Double> score=new HashMap<>();
		String token = httpServletRequest.getHeader("token");
		Claims claimByToken = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		Integer subject = Integer.valueOf(claimByToken.getSubject());
		List<AApplication> userId = aApplicationService.list(new QueryWrapper<AApplication>().eq("user_id", subject));
		userId.forEach(item->{
			AAuthentication authenticationServiceOne = aAuthenticationMapper.selectOne(new QueryWrapper<AAuthentication>()
					.eq("status", 0)
					.eq("active_id", item.getActiveId()));
			if (!(authenticationServiceOne==null))
			{
				AActive aActive = this.getOne(new QueryWrapper<AActive>()
						.eq("id", item.getActiveId()));
				if (!(aActive==null))
				{
					count+=1;
					if(aActive.getSecondScore()==1)
					{
						secondscore+=aActive.getScore();
					} else if (aActive.getEducationScore()==1) {
						educationscore+=aActive.getScore();
					} else if (aActive.getLaborScore()==1) {
						laborscore+=aActive.getScore();
					}
				}
			}
		});
		score.put("count",count);
		score.put("secondscore",secondscore);
		score.put("educationscore",educationscore);
		score.put("laborscore",laborscore);
		System.out.println(score);
		return score;
	}

	@Override
	public boolean deleteById(Integer id) {
		String projectPath = System.getProperty("user.dir") + "/file/";
		AActive byId = this.getById(id);

		Assert.notNull(byId, "抱歉，活动信息不存在");
		String path = byId.getFilePath();

		File file = new File(projectPath + path);
		if (file.exists()) {
			file.delete();
		}

		boolean b = this.update(new UpdateWrapper<AActive>()
				.eq("id", id)
				.set("is_delete", 1)
		);
		if (!b) {
			return false;
		}

		return true;
	}

	@Override
	public Object search(SearchVo searchVo) {
		System.out.println(searchVo);
		System.out.println(searchVo.getDepartment()+"---"+searchVo.getDepartment().isEmpty());
		List<AActive> list = this.list(new QueryWrapper<AActive>()
				.eq(searchVo.getStatus() != null, "status", searchVo.getStatus())
				.eq(searchVo.getType() != null, "type", searchVo.getType())

				.eq(!searchVo.getDepartment().isEmpty(), "department", searchVo.getDepartment())
				.ge(searchVo.getCreateTime() != null, "create_time", searchVo.getCreateTime())
				.le(searchVo.getDeadTime() != null, "dead_time", searchVo.getDeadTime())
				.like(!searchVo.getTitle().isEmpty(), "active_name", searchVo.getTitle())
		);
		return list;
	}



}




